
struct VS_IN_Pos
{
	float3 posL     : POSITION;
};

struct VS_IN_PosNorTanTex
{
	float3 posL     : POSITION;
	float3 normalL  : NORMAL0;
	float3 tangentL : TANGENT0;
	float2 texCoord : TEXCOORD0;
};

float2 encodeNormal(float3 normal)
{
	float2 res = 0.5f * (normal.xy + float2(1, 1));
	res.x = normal.z < 0 ? -res.x : res.x;
	return res;
}

float3 decodeNormal(float2 normal)
{
	float2 resXY = abs(normal) * 2 - float2(1,1);
	float3 res = float3(resXY, sqrt(1 - resXY.x * resXY.x - resXY.y * resXY.y));
	res.z = normal.x < 0 ? -res.z : res.z;
	return res;
}

// specPower assumed to be in range [0, 1024]
float encodeSpecPowerToUNorm(float specPower)
{
	const float oneOver1024 = 1.0f / 1024.0f;
	return specPower * oneOver1024;
}

// specPower assumed to be in range [0, 1024]
float decodeSpecPowerFromUNorm(float specPowerSNorm)
{
	return specPowerSNorm * 1024.0f;
}


DepthStencilState DepthOn
{
	DepthEnable = true;
};

DepthStencilState DepthOnRev
{
	DepthEnable = true;
	DepthFunc = GREATER;
};

DepthStencilState DepthOff
{
	DepthEnable = false;
};

DepthStencilState DepthWriteOff
{
	DepthEnable = true;
	DepthWriteMask = ZERO;
};

BlendState Additive
{
	BlendEnable[0] = TRUE;
	SrcBlend = ONE;
	DestBlend = ONE;
	BlendOp = ADD;
};

BlendState Composite
{
	BlendEnable[0] = TRUE;
	SrcBlend = SRC_ALPHA;
	DestBlend = INV_SRC_ALPHA;
	BlendOp = ADD;
};

BlendState NoBlend
{
  BlendEnable[0] = FALSE;
};

RasterizerState CullFront
{
	CullMode = FRONT;
	FillMode = SOLID;
};

RasterizerState CullFrontMS
{
	CullMode = FRONT;
	FillMode = SOLID;
	MultisampleEnable = TRUE;
};

RasterizerState CullBack
{
	CullMode = BACK;
	FillMode = SOLID;
};

RasterizerState CullBackMS
{
	CullMode = BACK;
	FillMode = SOLID;
	MultisampleEnable = TRUE;
};

RasterizerState CullNone
{
	CullMode = NONE;
	FillMode = SOLID;
};

RasterizerState Wireframe
{
	CullMode = BACK;
	FillMode = WIREFRAME;
};

SamplerState gPointSam
{
	Filter = MIN_MAG_MIP_POINT;
	AddressU = Clamp;
	AddressV = Clamp;
};

SamplerState gPointSamWrap
{
	Filter = MIN_MAG_MIP_POINT;
	AddressU = Wrap;
	AddressV = Wrap;
};

SamplerState gBilinearSam
{
	Filter = MIN_MAG_LINEAR_MIP_POINT;
	AddressU = Clamp;
	AddressV = Clamp;
};

SamplerState gTriLinearSam
{
	Filter = MIN_MAG_MIP_LINEAR;
	AddressU = Wrap;
	AddressV = Wrap;
};